package com.itfreer.gis.map.share;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.itfreer.data.metadata.DataDefinitionService;
import com.itfreer.data.metadata.DictionaryDirectoryService;
import com.itfreer.data.metadata.MetadataDirectoryService;
import com.itfreer.data.metadata.entity.DataDefinitionEntity;
import com.itfreer.data.metadata.entity.DataDictionaryDirectoryEntity;
import com.itfreer.data.metadata.entity.DataMetadataDirectoryEntity;
import com.itfreer.form.api.metadate.MetadataEntity;
import com.itfreer.form.api.metadate.MetadataService;
import com.itfreer.gis.map.resource.CustomServiceService;
import com.itfreer.gis.map.resource.entity.CustomServiceEntity;
import com.itfreer.gis.map.style.MapStyleDirectoryService;
import com.itfreer.gis.map.style.MapStyleLayerService;
import com.itfreer.gis.map.style.MapStyleService;
import com.itfreer.gis.map.style.MapStyleSpriteService;
import com.itfreer.gis.map.style.entity.MapStyleDirectoryEntity;
import com.itfreer.gis.map.style.entity.MapStyleEntity;
import com.itfreer.gis.map.style.entity.MapStyleLayerEntity;
import com.itfreer.gis.map.style.entity.MapStyleSourceEntity;
import com.itfreer.gis.map.style.entity.MapStyleSpriteEntity;

/**
 * 定义地图方案共享类
 */
@Component
public class MapShareImp implements MapShare {

	@Autowired
	private MapStyleDirectoryService mapStyleDirectoryService;
	@Autowired
	private MapStyleService mapStyleService;
	@Autowired
	private MapStyleLayerService mapStyleLayerService;
	@Autowired
	private MapStyleSpriteService mapStyleSpriteService;

	@Autowired
	private CustomServiceService customServiceService;
	@Autowired
	private MetadataDirectoryService metadataDirectoryService;
	@Autowired
	private MetadataService metadataService;
	@Autowired
	private DictionaryDirectoryService dictionaryDirectoryService;
	@Autowired
	private DataDefinitionService dataDefinitionService;

	/**
	 * 地图方案共享
	 * 
	 * @param ostyleId   需要复制的ID
	 * @param tenantID   共享的租户ID
	 * @param tenantName 共享的租户名称
	 * @throws Exception
	 */
	public void mapShare(String ostyleId, String tenantID, String tenantName) throws Exception {
		// 第一步：复制地图方案
		MapStyleDirectoryEntity mapStyleDirectoryEntity = mapStyleDirectoryService.getEntity(ostyleId);
		if (mapStyleDirectoryEntity == null) {
			return;
		}
		String directoryId = UUID.randomUUID().toString().replace("-", "");
		mapStyleDirectoryEntity.setId(directoryId);
		mapStyleDirectoryEntity.setTenantID(tenantID);
		mapStyleDirectoryEntity.setTenantName(tenantName);
		mapStyleDirectoryService.add(mapStyleDirectoryEntity);

		// 临时数据-共享过的元数据与字典
		List<String> shareMetadata = new ArrayList<>();
		List<String> shareDictionary = new ArrayList<>();

		// 第二步：根据地图方案，复制配图样式
		Map<String, Object> where = new HashMap<>();
		where.put("styleId", ostyleId);
		List<MapStyleEntity> styleList = mapStyleService.getEntitys(where, null);
		for (int i = 0; i < styleList.size(); i++) {
			Set<MapStyleLayerEntity> layers = new LinkedHashSet<>();
			Set<MapStyleSourceEntity> sources = new LinkedHashSet<>();
			String styleId = UUID.randomUUID().toString().replace("-", "");

			// 2.1 复制雪碧图
			MapStyleSpriteEntity mapStyleSpriteEntity = mapStyleSpriteService.getEntity(styleList.get(i).getSprite());
			String spriteId = UUID.randomUUID().toString().replace("-", "");
			mapStyleSpriteEntity.setId(spriteId);
			mapStyleSpriteEntity.setTenantID(tenantID);
			mapStyleSpriteEntity.setTenantName(tenantName);
			mapStyleSpriteService.add(mapStyleSpriteEntity);

			// 2.2 复制数据源
			Iterator<?> sourceIterator = styleList.get(i).getSources().iterator();
			while (sourceIterator.hasNext()) {
				MapStyleSourceEntity source = (MapStyleSourceEntity) sourceIterator.next();
				source.setId(UUID.randomUUID().toString().replace("-", ""));
				source.setTenantID(tenantID);
				source.setTenantName(tenantName);
				source.setStyleId(styleId);
				shareData(source, tenantID, tenantName, shareMetadata, shareDictionary);
				sources.add(source);
			}

			// 2.3 复制图层
			Iterator<?> layerIterator = styleList.get(i).getLayers().iterator();
			while (layerIterator.hasNext()) {
				MapStyleLayerEntity layer = (MapStyleLayerEntity) layerIterator.next();
				// 树形数据id随机生成，pid关系重新对应
				if (layer.getPid().equals("0")) {
					String oldId = layer.getId();
					String oldStyleId = layer.getStyleId();
					String layerId = UUID.randomUUID().toString().replace("-", "");

					layer.setTenantID(tenantID);
					layer.setTenantName(tenantName);
					layer.setStyleId(styleId);
					layer.setId(layerId);
					layers.add(layer);

					changeChildLayer(tenantID, tenantName, oldStyleId, styleId, oldId, layerId, layers);
				}
			}

			// 2.4 复制样式
			styleList.get(i).setTenantID(tenantID);
			styleList.get(i).setTenantName(tenantName);
			styleList.get(i).setId(styleId);
			styleList.get(i).setStyleId(directoryId);
			styleList.get(i).setSprite(spriteId);
			styleList.get(i).setSources(sources);
			styleList.get(i).setLayers(layers);
			mapStyleService.add(styleList.get(i));
		}
	}

	/**
	 * 共享数据
	 * 
	 * @param source
	 */
	private void shareData(MapStyleSourceEntity source, String tenantID, String tenantName, List<String> shareMetadata,
			List<String> shareDictionary) {
		// 第一步:共享服务
		customServiceService.share(source.getService(), tenantID, tenantName);
		CustomServiceEntity customServiceEntity = customServiceService.getEntity(source.getService());

		if (customServiceEntity != null) {
			// 第二步:共享数据
			if (customServiceEntity.getMetedata() != null) {
				dataDefinitionService.share(customServiceEntity.getMetedata(), tenantID, tenantName);

				DataDefinitionEntity dataDefinitionEntity = dataDefinitionService
						.getEntity(customServiceEntity.getMetedata());
				if (dataDefinitionEntity != null) {
					String m = dataDefinitionEntity.getMetadata();
					if (m != null) {
						// 第三步:共享结构
						if (!shareMetadata.contains(m)) {
							shareMetadata.add(m);
							metadataDirectoryService.share(m, tenantID, tenantName);
							shareUpMetadata(m, tenantID, tenantName, shareMetadata);
						}

						List<MetadataEntity> listEntitys = metadataService.getMetadata(m);
						if (listEntitys != null && listEntitys.size() > 0) {
							for (MetadataEntity entity : listEntitys) {
								String d = entity.getDictionaryName();
								if (d != null && !d.equals("")) {
									// 第四步:共享字典
									if (!shareDictionary.contains(d)) {
										shareDictionary.add(d);
										dictionaryDirectoryService.share(d, tenantID, tenantName);
										shareUpDictionary(d, tenantID, tenantName, shareDictionary);
									}
								}
							}
						}
					}
				}
			}
		}
	}

	private void shareUpMetadata(String id, String tenantID, String tenantName, List<String> shareMetadata) {
		DataMetadataDirectoryEntity metadataDirectoryEntity = metadataDirectoryService.getEntity(id);
		if (metadataDirectoryEntity != null && metadataDirectoryEntity.getPid() != null
				&& !metadataDirectoryEntity.getPid().equals("") && !metadataDirectoryEntity.getPid().equals("0")) {
			String pid = metadataDirectoryEntity.getPid();
			if (!shareMetadata.contains(pid)) {
				metadataDirectoryService.share(pid, tenantID, tenantName);
				shareMetadata.add(pid);
			}
			shareUpMetadata(pid, tenantID, tenantName, shareMetadata);
		}
	}

	private void shareUpDictionary(String id, String tenantID, String tenantName, List<String> shareDictionary) {
		DataDictionaryDirectoryEntity metadataDirectoryEntity = dictionaryDirectoryService.getEntity(id);
		if (metadataDirectoryEntity != null && metadataDirectoryEntity.getPid() != null
				&& !metadataDirectoryEntity.getPid().equals("") && !metadataDirectoryEntity.getPid().equals("0")) {
			String pid = metadataDirectoryEntity.getPid();
			if (!shareDictionary.contains(pid)) {
				dictionaryDirectoryService.share(pid, tenantID, tenantName);
				shareDictionary.add(pid);
			}
			shareUpDictionary(pid, tenantID, tenantName, shareDictionary);
		}
	}

	private void changeChildLayer(String tenantID, String tenantName, String oldStyleId, String newStyleId, String pid,
			String newLayerId, Set<MapStyleLayerEntity> layers) throws IOException {
		Map<String, Object> where = new HashMap<>();
		where.put("styleId", oldStyleId);
		where.put("pid", pid);
		List<MapStyleLayerEntity> styleLayers = mapStyleLayerService.getEntitys(where, null);

		for (int j = 0; j < styleLayers.size(); j++) {
			MapStyleLayerEntity layer = styleLayers.get(j);
			String layerId = layer.getId();
			String uuid = UUID.randomUUID().toString().replace("-", "");

			layer.setTenantID(tenantID);
			layer.setTenantName(tenantName);
			layer.setStyleId(newStyleId);
			layer.setPid(newLayerId);
			layer.setId(uuid);
			layers.add(layer);

			changeChildLayer(tenantID, tenantName, oldStyleId, layer.getStyleId(), layerId, uuid, layers);
		}
	}
}
